#ifndef CANSOCKET__CANSOCKET_HPP_
#define CANSOCKET__CANSOCKET_HPP_

//#include "serial/visibility_control.h"
#include <linux/can.h>
#include <net/if.h>
#include <linux/can/raw.h>
#include <vector>
#include <string>
#include <pthread.h>
#include <boost/container/static_vector.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

  /**
   * This is a CAN socket wrapper
   * Targets : Not copyable , Defined destructor
   * Can be constructed in place in a std::vector/std::array
   * Solution : Implement rule of 5
   * Use vector's emplace_back perfect forwarding and reserve functions to
   * avoid copy and moves
   */
// using namespace boost::asio; 
using namespace boost::asio;
struct can_rec_filter
{
  u_int16_t rec_id[8];
  int rec_id_sum[8];
  int16_t lun_speed_rec[4];
  int16_t lun_speed_set[4];
  int rec_id_count;

};

  class CanSocket
  {
  public:
    enum class SocketType : unsigned char
    {
      WRITE_ONLY,
      READ_ONLY,
      READ_WRITE
    };
    int read_can_flag;
    CanSocket(const char * canNo);
   ~CanSocket();
    /**
     *  Need to maintain a move policy
     *  a Move from the socket keeps it in an invalid state
     */
    int thread_ret;
    void write_can(unsigned char* sd ,u_int16_t id ) ;
     void run();
    void* read_can();
    void add_can_filter(u_int16_t id);
    int get_rec_flag(void);
    u_char * get_rec_str();
    void write_lun(void);
    void set_lun_speed(int16_t sp,int index);
  private:
    /**
     * This is an example offset, the CAN_SOCKET mask
     * depends on the user's chosen CAN_ID design
     * The Can Socket is configured to receive only those messages which match this condition : canID|CAN_ID_OFFSET
     * For example, if the IDs for this socket are 0x01 0x02 ;
     * then this socket will receive can messages with 0x06 and 0x07
     */
    struct can_frame can_send_fram[2]={{0}};
    struct can_frame can_rec_fram[2]={{0}};
    int open_id;
    can_rec_filter rec_id;
    /// @brief 
    sockaddr_can addr;
    ifreq ifr;
   // pthread_t my_thread;
    
    std::thread send_thread_;
    std::thread read_thread_;
    void runThreadFunc(void);
  };

 // namespace cansocket

#endif // CANSOCKET__CANSOCKET_HPP_
